/*
 * Copyright (C) 2025 SDFX Project
 * SDFX is licensed under Mulan PSL v2.
 */

/**
 * @file daemon_internal.h
 * @brief SDFX daemon internal interface definitions
 */

#ifndef DAEMON_INTERNAL_H
#define DAEMON_INTERNAL_H

#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#include <pthread.h>
#include <sys/socket.h>

#include "sdf_types.h"
#include "sdf_err.h"
#include "sdfx.h"
#include "protocol.h"
#include "log.h"

#ifdef __cplusplus
extern "C" {
#endif

/* Session information structure */
typedef struct session_info {
    uint32_t session_id;
    uint32_t device_handle;
    time_t create_time;
    time_t last_access;
    bool active;
    
    /* Reference counting for thread safety */
    int ref_count;
    pthread_mutex_t ref_mutex;
    
    /* Crypto contexts */
    void *hash_ctx;
    void *cipher_ctx;
    
    struct session_info *next;
} session_info_t;

/* Daemon context */
typedef struct daemon_context {
    /* Transport layer */
    void *transport_ctx;
    
    /* Session management */
    session_info_t *sessions;
    pthread_mutex_t sessions_mutex;
    uint32_t next_session_id;
    uint32_t next_device_id;
    
    /* Control flags */
    volatile bool running;
    
    /* Statistics */
    uint64_t total_requests;
    uint32_t active_sessions_count;
} daemon_context_t;

/* Function declarations */

/* Thread pool */
int thread_pool_create(int thread_count);
void thread_pool_destroy(void);
int thread_pool_submit(void (*function)(void*), void *arg);
int thread_pool_get_stats(int *thread_count, int *queue_size);

/* Daemon core */
int daemon_core_init(daemon_context_t *ctx);
int daemon_core_init_with_config(daemon_context_t *ctx, const void *config);
void daemon_core_cleanup(daemon_context_t *ctx);
int daemon_core_run(daemon_context_t *ctx);
daemon_context_t* daemon_get_context(void);

/* Session management */
int session_manager_init(daemon_context_t *ctx);
void session_manager_cleanup(daemon_context_t *ctx);
uint32_t session_manager_create_session(daemon_context_t *ctx, uint32_t device_handle);
int session_manager_close_session(daemon_context_t *ctx, uint32_t session_id);
int session_manager_validate_session(daemon_context_t *ctx, uint32_t session_id);
/* DEPRECATED: Use session_manager_get_session() instead to avoid race conditions */
session_info_t* session_manager_find_session_deprecated(daemon_context_t *ctx, uint32_t session_id);

/* Session reference counting for thread safety */
session_info_t* session_manager_get_session(daemon_context_t *ctx, uint32_t session_id);
void session_manager_put_session(session_info_t *session);

/* Protocol Handler */
int protocol_handler_init(daemon_context_t *ctx);
void protocol_handler_cleanup(daemon_context_t *ctx);
int protocol_handler_process_message(daemon_context_t *ctx, 
                                    const sdfx_message_t *request,
                                    sdfx_message_t **response,
                                    size_t *response_size);

/* Device management */
uint32_t device_manager_create_device(daemon_context_t *ctx);
int device_manager_validate_device(daemon_context_t *ctx, uint32_t device_handle);

/* Random Number Generation */
int crypto_generate_random(uint32_t length, BYTE *output);
void crypto_engine_cleanup(void);

/* Hash Algorithm */
int crypto_hash_init(daemon_context_t *ctx, session_info_t *session, ULONG alg_id);
int crypto_hash_update(daemon_context_t *ctx, session_info_t *session, 
                      const BYTE *data, ULONG data_len);
int crypto_hash_final(daemon_context_t *ctx, session_info_t *session,
                     BYTE *hash, ULONG *hash_len);
int crypto_hash_digest(ULONG alg_id, const BYTE *data, ULONG data_len,
                      BYTE *hash, ULONG *hash_len);

/* Symmetric Cryptography */
int crypto_symmetric_encrypt(ULONG alg_id, const BYTE *key, ULONG key_len,
                            const BYTE *iv, ULONG iv_len,
                            const BYTE *plaintext, ULONG plaintext_len,
                            BYTE *ciphertext, ULONG *ciphertext_len);
int crypto_symmetric_decrypt(ULONG alg_id, const BYTE *key, ULONG key_len,
                            const BYTE *iv, ULONG iv_len,
                            const BYTE *ciphertext, ULONG ciphertext_len,
                            BYTE *plaintext, ULONG *plaintext_len);

/* SM2 Asymmetric Cryptography */
int crypto_sm2_internal_sign(ULONG key_index, const BYTE *data, ULONG data_len,
                            BYTE *signature, ULONG *signature_len);
int crypto_sm2_internal_verify(ULONG key_index, const BYTE *data, ULONG data_len,
                              const BYTE *signature, ULONG signature_len);
int crypto_sm2_external_encrypt(const ECCrefPublicKey *public_key,
                               const BYTE *plaintext, ULONG plaintext_len,
                               BYTE *ciphertext, ULONG *ciphertext_len);
int crypto_sm2_external_decrypt(const ECCrefPrivateKey *private_key,
                               const BYTE *ciphertext, ULONG ciphertext_len,
                               BYTE *plaintext, ULONG *plaintext_len);
int crypto_sm2_external_sign(const ECCrefPrivateKey *private_key,
                            const BYTE *data, ULONG data_len,
                            BYTE *signature, ULONG *signature_len);
int crypto_sm2_external_verify(const ECCrefPublicKey *public_key,
                              const BYTE *data, ULONG data_len,
                              const BYTE *signature, ULONG signature_len);
int crypto_sm2_generate_keypair(ECCrefPublicKey *public_key, ECCrefPrivateKey *private_key);

/* SM2 context management */
void crypto_sm2_cleanup_contexts(void);

#ifdef __cplusplus
}
#endif

#endif /* DAEMON_INTERNAL_H */